//UserMGR.cpp

//Use for MySQL++ API Library
#include <mysql++.h>

#include "UserMGR.h"
#include "TagMGR.h"
#include <string>

//Namespcases
using namespace mysqlpp;
using namespace std;


//////////////////////////////////////////////////////////////////////////////////////////
// Constructor & Destructor																//
//////////////////////////////////////////////////////////////////////////////////////////

//Constructor
UserMGR::UserMGR():users()
{
	this->count = 0;
}


//Desturctor
UserMGR::~UserMGR()
{
}


//Copy Constructor
UserMGR::UserMGR(const UserMGR& source):users(source.users)
{
	this->count = source.count;
}


//////////////////////////////////////////////////////////////////////////
// Operators															//
//////////////////////////////////////////////////////////////////////////

// = Operator
UserMGR& UserMGR::operator = (const UserMGR& source)
{
	this->count = source.count;
	this->users = source.users;

	return (*this);
}


// [] Operator
UserInformation& UserMGR::operator [] (int index)
{
	    return const_cast<UserInformation&>(this->users[index]);
}




//////////////////////////////////////////////////////////////////////////
// Member Functions														//
//////////////////////////////////////////////////////////////////////////

//Record
UserInformation* UserMGR::Record( UserInformation userInformation )
{
	UserInformation* ret = NULL;
	
	Node<UserInformation>* insertedPosition = NULL;
	insertedPosition = this->users.AppendFromTail(userInformation);

	if( insertedPosition != NULL)
	{
		ret = &(insertedPosition->GetObject());
		(this->count)++;

		//Open the Database
		Connection con( "rss", "localhost", "root", "dreams" );

		//SetUp Query Variable
		Query query = con.query();

		try {
			/*예전 쿼리
			//Set Query
			query << "call InsertUserInformation( \""
				  << const_cast<char*>( userInformation.GetEmailAddress().c_str() ) << "\", \""
				  << const_cast<char*>( userInformation.GetmacAddress().c_str() ) << "\", \""
				  << const_cast<char*>( userInformation.GetPassword().c_str() ) << "\", \""
				  << const_cast<char*>( userInformation.GetName().c_str() ) << "\")";
			*/
			//변경된 쿼리
			query << "insert into UserInformation values ( \""
				<< const_cast<char*>( userInformation.GetEmailAddress().c_str() ) << "\", \""
				<< const_cast<char*>( userInformation.GetPassword().c_str() ) << "\", \""
				<< const_cast<char*>( userInformation.GetmacAddress().c_str() ) << "\", \""
				<< const_cast<char*>( userInformation.GetName().c_str() ) << "\")";

	//		query.parse();

			//Execute Query
			query.execute();
		}
		catch( const BadQuery& er )
		{
			cerr << "Query Error : " << er.what() << endl;
		}		
	}

	return ret;

}


//<--------Find By MacAddress------->

//Compare Function
int CompareBymacAddress(void* one, void* other)
{
	int ret = -1;
	if( ((UserInformation*)one)->GetmacAddress() == *((string*)other) )
	{
		ret = 0;
	}
	return 0;
} 

//Find By MacAddress
UserInformation* UserMGR::Find(string macAddress)
{
	Node<UserInformation>* findNode = NULL;
	UserInformation* ret = NULL;

	findNode = this->users.LinearSearchUnique(&macAddress, CompareBymacAddress);

	if(findNode != NULL)
	{
		ret = &(findNode->GetObject());
	}

	return ret;
}


//<-------------- Find By MacAddress End -------------->

//Find By UserInformation
void UserMGR::Find(UserInformation* user, unsigned int* count, Tag*** searchedTaglist)
{
	*count = 0;
	*count = user->GetBookMarkList()->GetCount();
	*searchedTaglist = new Tag*[*count];

	int i = 0;
	
	for( i = 0; i < *count ; i++)
	{
		(*searchedTaglist)[i] = (user->GetBookMarkList()->GetTag(i));
	}

}



//Insert BookMark at Database
void UserMGR::InsertBookMark( string title, string emailAddress )
{
	//Open the Database
	Connection con( "rss", "localhost", "root", "dreams" );

	//Declaration Query Varialbe
	Query query = con.query();

	try {
		//Set Query
		/*예전 쿼리
		query << "call InsertBookMark( \""
			  << const_cast<char*>( emailAddress.c_str() ) << "\", \""
			  << const_cast<char*>( title.c_str() ) << "\" )";
		 */
		query << "insert into Bookmark values (\""
			<< const_cast<char*>( emailAddress.c_str() ) << "\", \""
			<< const_cast<char*>( title.c_str() ) << "\" )";

	}
	catch( const BadQuery& er )
	{
		cerr << "Query error : " << er.what() << endl;
	}	
}


//////////////////////////////////////////////////////////////////////////////////////////
//                                                                                      //
//  Database Load : Get Data from the Database (Channel Table)                          //
//  Creator : Taek han, Go(FreeMan)                                                     //
//  Revision Date : 2007/01/13                                                          //
//  Perpose : Load the date from the Datebase                                           //
//  Information : Datetime Datatye is imperfect.(Don't know the use)                    //
//                                                                                      //
//////////////////////////////////////////////////////////////////////////////////////////
#if 1
void UserMGR::LoadDB()
{
	//Open the Database( DB Name : rss, Host Name : localhost, ID : root, Password : dreams )
	Connection con( "rss", "localhost", "root", "dreams" );

	//Declaration Query Variable
	Query query = con.query();

	//Declaration Result Variable
	Result res = 0;

	//Declaration Row Variable
	Row row;

	Row::size_type i;

	int count = 0;

	//////////////////////////////////////////////////////////////////////////
	// Load BookMark														//
	//////////////////////////////////////////////////////////////////////////
	
	//Set Query for get the data from the BookMark table
	query << "select BookMark.emailAddress, BookMark.title from BookMark;";

	res = query.store();

	count = res.num_rows();

	if( count > 0 )
	{
		row = res.fetch_row();
	
		//Definition EmailAddress 
		struct EmailAddress {
			string emailAddress;
		};
	
		//Set EmailAddress Struct Array
		EmailAddress* emailAddress = new EmailAddress[ res.num_rows() ];
	
		//Declare new BookMarkList Object in the heep space
		BookMarkList* originalBookMarkList = new BookMarkList;
		
		try {
			//ResultsSet 
			for( i = 0; row = res.at(i); ++i )
			{
				//Save the data of emailAddress into EmailAddress Struct
				emailAddress[i].emailAddress = string( row.raw_data(0) );
				
				//Create Tag Object
				Tag originalTag( string( row.raw_data(1) ) );
	
				//Declaration Tag Object in heep space
				Tag* originalTag_ = new Tag;
				
				//Copy Tag Object to another Tag Object located in heep space
				*originalTag_ = originalTag;
				
				//Create BookMark Object
				BookMark originalBookMark( originalTag_ );
	
				//Declaration BookMark Object in heep space
				BookMark* originalBookMark_ = new BookMark;
	
				//Copy BookMark Object to another BookMark Oject located in heep space
				*originalBookMark_ = originalBookMark;
		
				//Append BookMark to BookMariList
				BookMark* returnBookmark = originalBookMarkList->TakeIn( originalBookMark_ );
			}
		}
		catch( const EndOfResults& end )
		{
		}
		//<------------------------- Load BookMark End ------------------------->


		//Reset Result Variable
		res = 0;

	
		/////////////////////////////////////////////////////////////////////////
		// Load UserInformation												   //
		/////////////////////////////////////////////////////////////////////////
	
		//Set Query for get the data from the UserInformation Table
		query << "select UserInformation.emailAddress, UserInformation.macAddress, UserInformation.password "
			  << "UserInformation.name from UserInformation;";
	
		res = query.store();
	
		count = res.num_rows();
	
		if( count > 0 )
		{
			row = res.fetch_row();
	
			try {
				//Loop for Create UserInformation Object
				for( i = 0; row = res.at(i); ++i )
				{
					//Create BookMarkList Object located in heep space
					BookMarkList* newBookMarkList = new BookMarkList;
					
					//Get EmailAddress from ResultSet
					string emailAddress_ = string( row.raw_data(0) );
		
					//Create new BookMarkList
					for( int j = 0; j < originalBookMarkList->GetCount(); j++ )
					{
						if( emailAddress_ == emailAddress[j].emailAddress )
						{
							//GetTag
							Tag* tag = originalBookMarkList->GetTag(j);
		
							//Create BookMark Object
							BookMark newBookMark( tag );
						
							//Declaration BookMark Object in heep space
							BookMark* newBookMark_ = new BookMark;
		
							//Copy BookMark Object to another BookMark Oject located in heep space
							*newBookMark_ = newBookMark;
											
							//Add BookMark at BookMarkList
							newBookMarkList->TakeIn( newBookMark_ );
						}
					}//for loop end
				
					//Get macAddress from UserInformation Table
					string macAddress = string( row.raw_data(1) );
		
					//Get password from UserInformation Table
					string password = string( row.raw_data(2) );

					//Get name from UserInformation Table
					string name = string( row.raw_data(3) );
		
					//Create UserInformation Object
					UserInformation user( emailAddress_, macAddress, password, name, newBookMarkList );
		
					//Declaration UserInformation Object in heep space
					UserInformation* user_ = new UserInformation;
		
					*user_ = user;
		
					//Add UserInformation at UserMGR
					this->Record( *user_ );
		
				//	delete newBookMarkList;
				}
				//delete originalBookMarkList
				delete originalBookMarkList;
			}
			catch( const EndOfResults& end )
			{
			}	  
		//<-------------------- Loade UserInformation End ----------------------->	
		}
	}
}
#endif

